home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue64 / WBroker / main.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2000-10-01  |  9.8 KB  |  334 lines

  1. unit Main;
  2. { $M 40960, 8192}
  3.  
  4. interface
  5.  
  6. uses
  7.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  8.   Forms, Dialogs, FileCtrl, StdCtrls, Buttons, Outline, ExtCtrls, Tabs,
  9.   Grids, NewParse, HTTPApp;
  10.  
  11. type
  12.   TCVCSMain = class(TForm)
  13.     Panel1: TPanel;
  14.     Panel2: TPanel;
  15.     SpeedButton2: TSpeedButton;
  16.     SpeedButton1: TSpeedButton;
  17.     SaveDialog1: TSaveDialog;
  18.     CheckBox1: TCheckBox;
  19.     Label4: TLabel;
  20.     ComboBox1: TComboBox;
  21.     DriveComboBox1: TDriveComboBox;
  22.     Label1: TLabel;
  23.     Label3: TLabel;
  24.     ListBox1: TListBox;
  25.     Outline1: TOutline;
  26.     DirectoryListBox1: TDirectoryListBox;
  27.     FileListBox1: TFileListBox;
  28.     Label2: TLabel;
  29.     PageProducer1: TPageProducer;
  30.     procedure FileListBox1DblClick(Sender: TObject);
  31.     procedure SpeedButton2Click(Sender: TObject);
  32.     procedure FormCreate(Sender: TObject);
  33.     procedure FormDestroy(Sender: TObject);
  34.     procedure SpeedButton1Click(Sender: TObject);
  35.     procedure PageProducer1HTMLTag(Sender: TObject; Tag: TTag;
  36.       const TagString: String; TagParams: TStrings;
  37.       var ReplaceText: String);
  38.   private
  39.     { Private declarations }
  40.     ExcludeList: TStringList;
  41.     procedure BuildList(FName: string; var Level: integer);
  42.     function Parse(var ParseStr: string): string;
  43.     function GetUsesClause(FName: string): string;
  44.     procedure FindUnit(var FName: string);
  45.   public
  46.     { Public declarations }
  47.   end;
  48.  
  49. var
  50.   CVCSMain: TCVCSMain;
  51.  
  52. implementation
  53.  
  54. {$R *.DFM}
  55.  
  56. { GetUsesClause - routine to extract the uses clause from a unit }
  57. function TCVCSMain.GetUsesClause(FName: string): string;
  58. var
  59.   AStream: TFileStream;
  60.   Parser: TCustomParser;
  61.   BeginCopy,
  62.   FoundUses,
  63.   IsComment: boolean;
  64.   S: string;
  65. begin
  66.   { initiallize variables }
  67.   Result := '';
  68.   BeginCopy := false;
  69.   FoundUses := false;
  70.   IsComment := false;
  71.   try
  72.     { open FileStream(FName) }
  73.     AStream := TFileStream.Create(FName, fmOpenRead);
  74.     { create unit parser }
  75.     Parser := TEnhPasParser.Create(AStream);
  76.     try
  77.       with Parser do
  78.         while Token <> toEOF do
  79.         begin
  80.           S := TokenString;
  81.           case Token of
  82.             toSymbol: begin
  83.                 if (TokenString = 'implementation') and not IsComment then
  84.                   FoundUses := true;
  85.                 if (TokenString = 'uses') and not IsComment then
  86.                 begin
  87.                   BeginCopy := true;
  88.                   S := '';
  89.                 end;
  90.               end;
  91.             ';': begin
  92.                 if FoundUses then Exit;
  93.                 if BeginCopy then
  94.                 begin
  95.                   AppendStr(Result, ',');
  96.                   BeginCopy := false;
  97.                 end;
  98.               end;
  99.             '{': begin
  100.                 S := '';
  101.                 IsComment := true;
  102.               end;
  103.             '}': begin
  104.                 S := '';
  105.                 IsComment := false;
  106.               end;
  107.           end;
  108.           if BeginCopy and not IsComment then AppendStr(Result, S);
  109.           NextToken;
  110.         end;
  111.     finally
  112.       Parser.Free;
  113.       AStream.Free;
  114.     end;
  115.   except
  116.     { on file open error return empty string }
  117.     on EFOpenError do Result := '';
  118.   end;
  119. end;
  120.  
  121. { Parse - routine to parse the uses clause }
  122. function TCVCSMain.Parse(var ParseStr: string): string;
  123. var
  124.   Len: integer;
  125. begin
  126.   Result := '';
  127.   if Length(ParseStr) > 0 then { if there is something to parse... }
  128.   begin
  129.     repeat
  130.       if Pos(',', ParseStr) <> 0 then  { if there is a comma... }
  131.       begin
  132.         { copy up to it }
  133.         Len := Pos(',', ParseStr);
  134.         Result := System.Copy(ParseStr, 1, Len-1);
  135.       end else
  136.       begin
  137.         { else copy all remaining string }
  138.         Len := Length(ParseStr);
  139.         Result := System.Copy(ParseStr, 1, Len);
  140.       end;
  141.       { delete what we copied }
  142.       System.Delete(ParseStr, 1, Len);
  143.       { if we have a valid unit name... }
  144.       if IsValidIdent(Result) then Result := Result+'.pas' { add .pas extension }
  145.       else Result := ''; { else return empty string }
  146.     { ...until there is a unit NOT in the exclude list }
  147.     until (ExcludeList.IndexOf(Result) < 0);
  148.   end;
  149. end;
  150.  
  151. procedure TCVCSMain.FindUnit(var FName: string);
  152. var
  153.   FN, TempStr: string;
  154. begin
  155.   FN := FName; { set FN equal to FName }
  156.   { perform the search }
  157.   TempStr := FileSearch(FN, ComboBox1.Text);
  158.   { if successful change FName }
  159.   if TempStr <> '' then FName := ExpandFileName(TempStr);
  160. end;
  161.  
  162. { BuildList - recursive routine to ''walk'' the units tree }
  163. procedure TCVCSMain.BuildList(FName: string; var Level: integer);
  164. var
  165.   NextFile, Remaining: string;
  166.   Idx: integer;
  167. begin
  168.   { find the file on the path }
  169.   FindUnit(FName);
  170.   { add node for file }
  171.   Idx := Outline1.Add(Outline1.SelectedItem, FName);
  172.   Outline1.Items[Idx].Level := Level;
  173.   { add file to exclude list to avoid infinite
  174.     recursion from circular unit references }
  175.   ExcludeList.Add(ExtractFileName(FName));
  176.   { get the uses clause from FName }
  177.   Remaining := GetUsesClause(FName);
  178.   { parse the units clause }
  179.   NextFile := Parse(Remaining);
  180.   while NextFile <> '' do { if NextFile is not empty... }
  181.   begin
  182.     { Inc tree level }
  183.     Inc(Level);
  184.     { recurse with first dependant file }
  185.     BuildList(NextFile, Level);
  186.     { find next dependant file }
  187.     NextFile := Parse(Remaining);
  188.     { Dec tree level }
  189.     Dec(Level);
  190.   end;
  191. end;
  192.  
  193. procedure TCVCSMain.FileListBox1DblClick(Sender: TObject);
  194. var
  195.   L: integer;
  196. begin
  197.   L := 1;
  198.   Screen.Cursor := crHourglass;
  199.   try
  200.     { clear the exclude list }
  201.     ExcludeList.Clear;
  202.     { if user want''s to use the exclude list... }
  203.     if CheckBox1.Checked then ExcludeList.Assign(ListBox1.Items);
  204.     { call BuildList to fill the Outline }
  205.     BuildList(FileListBox1.Items[FileListBox1.ItemIndex], L);
  206.     { Expand the Outline }
  207.     Outline1.FullExpand;
  208.   finally
  209.     Screen.Cursor := crDefault;
  210.   end;
  211. end;
  212.  
  213. procedure TCVCSMain.SpeedButton2Click(Sender: TObject);
  214. begin
  215.   { clear the Outline }
  216.   Outline1.Clear;
  217. end;
  218.  
  219. procedure TCVCSMain.FormCreate(Sender: TObject);
  220. begin
  221.   { create the exclude list }
  222.   ExcludeList := TStringList.Create;
  223.   ExcludeList.Sorted := true;
  224.   ExcludeList.Duplicates := dupIgnore;
  225.   { add possible exclude items to the list box }
  226.   ListBox1.Items.Add ('Windows.pas');
  227.   ListBox1.Items.Add ('WinTypes.pas');
  228.   ListBox1.Items.Add ('WinProcs.pas');
  229.   ListBox1.Items.Add ('SysUtils.pas');
  230.   ListBox1.Items.Add ('System.pas');
  231.   ListBox1.Items.Add ('Classes.pas');
  232.   ListBox1.Items.Add ('ClipBrd.pas');
  233.   ListBox1.Items.Add ('Messages.pas');
  234.   ListBox1.Items.Add ('Graphics.pas');
  235.   ListBox1.Items.Add ('Controls.pas');
  236.   ListBox1.Items.Add ('Consts.pas');
  237.   ListBox1.Items.Add ('ComCtrls.pas');
  238.   ListBox1.Items.Add ('Forms.pas');
  239.   ListBox1.Items.Add ('Dialogs.pas');
  240.   ListBox1.Items.Add ('Menus.pas');
  241.   ListBox1.Items.Add ('Mask.pas');
  242.   ListBox1.Items.Add ('Outline.pas');
  243.   ListBox1.Items.Add ('StdCtrls.pas');
  244.   ListBox1.Items.Add ('ExtCtrls.pas');
  245.   ListBox1.Items.Add ('FileCtrl.pas');
  246.   ListBox1.Items.Add ('Buttons.pas');
  247.   ListBox1.Items.Add ('Tabs.pas');
  248.   ListBox1.Items.Add ('TabNotBk.pas');
  249.   ListBox1.Items.Add ('HTTPApp.pas');
  250.   ListBox1.Items.Add ('Grids.pas');
  251.   ListBox1.Items.Add ('Printers.pas');
  252.   ListBox1.Items.Add ('DDEMan.pas');
  253.   ListBox1.Items.Add ('MPlayer.pas');
  254.   ListBox1.Items.Add ('TOCtrl.pas');
  255.   ListBox1.Items.Add ('IniFiles.pas');
  256.   ListBox1.Items.Add ('DsgnIntf.pas');
  257.   ListBox1.Items.Add ('ToolIntf.pas');
  258.   ListBox1.Items.Add ('DB.pas');
  259.   ListBox1.Items.Add ('DBTables.pas');
  260.   ListBox1.Items.Add ('DBLookup.pas');
  261.   ListBox1.Items.Add ('DBGrids.pas');
  262.   ListBox1.Items.Add ('DBiTypes.pas');
  263.   ListBox1.Items.Add ('DBiProcs.pas');
  264.   ListBox1.Items.Add ('DBCtrls.pas');
  265.   ListBox1.Items.Add ('DBiErrs.pas');
  266.   { assign ListBox1.Items to exclude list
  267.     since this is the default }
  268.   ExcludeList.Assign(ListBox1.Items);
  269. end;
  270.  
  271. procedure TCVCSMain.FormDestroy(Sender: TObject);
  272. begin
  273.   { free the exclude list }
  274.   ExcludeList.Free;
  275. end;
  276.  
  277. procedure TCVCSMain.SpeedButton1Click(Sender: TObject);
  278. begin
  279.   with TStringList.Create do
  280.   try
  281.     if SaveDialog1.Execute then
  282.     begin
  283.       Text := PageProducer1.Content;
  284.       SaveToFile(SaveDialog1.FileName);
  285.     end;
  286.   finally
  287.     Free;
  288.   end;
  289. end;
  290.  
  291. procedure TCVCSMain.PageProducer1HTMLTag(Sender: TObject; Tag: TTag;
  292.   const TagString: String; TagParams: TStrings; var ReplaceText: String);
  293. var
  294.   i, j: integer;
  295.   CurLev: Cardinal;
  296. begin
  297.   CurLev := 0;
  298.  
  299.   if (CompareText(TagString, 'Title') = 0) or (CompareText(TagString, 'Heading') = 0) then
  300.     ReplaceText := 'Packing List';
  301.  
  302.   if (CompareText(TagString, 'Root') = 0) then
  303.     ReplaceText := Format('%s', [Outline1.Items[1].Text]);
  304.  
  305.   if CompareText(TagString, 'List') = 0 then
  306.   begin
  307.     for i := 0 to Outline1.Lines.Count-1 do
  308.     begin
  309.       { if level goes up... }
  310.       if Outline1.Items[i+1].Level > CurLev then
  311.       begin
  312.         ReplaceText := ReplaceText + '<UL>'; { increase indent }
  313.         Inc(CurLev);      { increase CurLev }
  314.       end;
  315.       { if level goes down... }
  316.       if Outline1.Items[i+1].Level < CurLev then
  317.         { for CurLev down to the new level }
  318.         for j := CurLev downto Outline1.Items[i+1].Level+1 do
  319.         begin
  320.           ReplaceText := ReplaceText + '</UL>'; { close list level }
  321.           Dec(CurLev);  { decrease CurLev }
  322.         end;
  323.       ReplaceText := ReplaceText + #13#10;
  324.       ReplaceText := ReplaceText + '<LI>'+Outline1.Items[i+1].Text; { write out the actual text }
  325.     end;
  326.     for j := CurLev downto 0 do ReplaceText := ReplaceText + '</UL>'; { close all list levels }
  327.     { Html footer }
  328.     ReplaceText := ReplaceText + '<HR>'#13#10'Generated by <b>PackList</b> from';
  329.     ReplaceText := ReplaceText + ' HomeGrown Software, by Paul Warren.';
  330.   end;
  331. end;
  332.  
  333. end.
  334.